//
// Unihan Input Method
//
// Copyright © 2002-2007 Sun Wah Linux Ltd.
//
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
// USA
//
// $Id: ui.c 793 2007-06-26 15:06:44Z roger $
//

#include "ui.h"
#include "core.h"
#include "unicode.h"
#include "unihan_xaux.h"

#include <stdio.h>
#include <string.h>

static void init_imtext_feedbacklist(iml_session_t *s, IMText *text);

/***************************************************************************/
static void
status_update_aux(iml_session_t *s)
{
        DataPerSession *ds = (DataPerSession *)s->specific_data;
        
#if 0        
        int int_values[21];
        UTFCHAR *string_values[21];
        UnihanPropertyArgList proplist;
    	int num_string = 1;
    	
    	int_values[0] = UNIHAN_AUX_STATUS_SWITCH_IM;
		
	if (ds->conv_on) {
		string_values[0] = utf8_to_utf16be(s, im_get_curr_im_name(s), NULL);
		proplist = im_get_current_im_props(s);

		if(proplist->type)
			num_string = convert_props_to_string(s,
					proplist,
					255,
					int_values,
					string_values);
        } else {
                string_values[0] = utf8_to_utf16be(s, "English", NULL);
        }
        
	aux_draw(s, AUX_STATUS_CLASS_NAME, num_string, int_values, num_string, string_values);
#endif
	
        int int_values[1];
        UTFCHAR *string_values[1];

        int_values[0] = UNIHAN_AUX_STATUS_SWITCH_IM;

        if (ds->conv_on != 0) {
#if NEW_PROPERTY
				string_values[0] = utf8_to_utf16be(s, im_get_curr_im_id(s), NULL);
#else
                string_values[0] = utf8_to_utf16be(s, (UTF8CHAR *)im_get_curr_im_name(s), NULL);
#endif
        } else {
                string_values[0] = utf8_to_utf16be(s, (UTF8CHAR *)"English", NULL);
        }

        aux_draw(s, AUX_STATUS_CLASS_NAME, 1, int_values, 1, string_values);

        return;
}


/***************************************************************************/
void
status_update(iml_session_t *s)
{
	DataPerDesktop *dd = (DataPerDesktop *)s->desktop->specific_data;
	DataPerSession *ds = (DataPerSession *)s->specific_data;
	iml_inst *lp, *rrv = NULL;
	char *status_text = NULL;
	IMText *text = (IMText *)s->If->m->iml_new(s, sizeof(IMText));
	memset(text, 0, sizeof(IMText));

	if (is_status_started(dd->aux_started)) {
		if (is_status_started(ds->ui_started)) {
            static UTFCHAR empty_string[1] = { 0 };
			text->encoding = UTF16_CODESET;
			text->text.utf_chars = empty_string;
			init_imtext_feedbacklist(s, text);
			lp = s->If->m->iml_make_status_draw_inst(s, text);
			s->If->m->iml_link_inst_tail(&rrv, lp);
			lp = s->If->m->iml_make_status_done_inst(s);
			s->If->m->iml_link_inst_tail(&rrv, lp);
			s->If->m->iml_execute(s, &rrv);
			ds->ui_started &= ~STATUS_STARTED;
		}
		return status_update_aux(s);
	}

	if (!is_status_started(ds->ui_started)) {
		lp = s->If->m->iml_make_status_start_inst(s);
		s->If->m->iml_link_inst_tail(&rrv, lp);
		ds->ui_started |= STATUS_STARTED;
	}

	if (ds->conv_on != 0) {
		status_text = im_get_curr_im_name(s);
	} else {
		status_text = "English";
	}

	text->encoding = UTF16_CODESET;
	text->text.utf_chars = utf8_to_utf16be(s, (UTF8CHAR *)status_text, &text->char_length);
		
	init_imtext_feedbacklist(s, text);
	lp = s->If->m->iml_make_status_draw_inst(s, text);
	s->If->m->iml_link_inst_tail(&rrv, lp);

	s->If->m->iml_execute(s, &rrv);	
		
#if 0	
	int int_values[1];
	UnihanPropertyArgList prop;
 
	prop = im_get_runtime_property(s, UNIHAN_RUNTIME_PROPERTY_FULL_HALF, 0);

	if(prop->type) {
		if(prop->UnihanProperty.rt_property.value)
			int_values[0] = UNIHAN_AUX_STATUS_FULLWIDTH;
    		else
			int_values[0] = UNIHAN_AUX_STATUS_HALFWIDTH;
		aux_draw(s, AUX_STATUS_CLASS_NAME, 1, int_values, 0, NULL);
	}	

	prop = im_get_runtime_property(s, UNIHAN_RUNTIME_PROPERTY_PUNC_EN_CH, 0);

	if(prop->type) {
		if(prop->UnihanProperty.rt_property.value)
			int_values[0] = UNIHAN_AUX_STATUS_CHINESEPUNC;
		else
			int_values[0] = UNIHAN_AUX_STATUS_ENGLISHPUNC;
		aux_draw(s, AUX_STATUS_CLASS_NAME, 1, int_values, 0, NULL);
	}
#endif
}


/***************************************************************************/
static void
init_imtext_feedbacklist(iml_session_t *s, IMText *text)
{
	IMFeedbackList *feedback = s->If->m->iml_new(s, 
			text->char_length * sizeof(IMFeedbackList));
	memset(feedback, 0, text->char_length * sizeof(IMFeedbackList));
	text->feedback = feedback;
}


void
aux_start(iml_session_t *s, char *class_name)
{
    IMAuxStartCallbackStruct *aux = (IMAuxStartCallbackStruct *)
        s->If->m->iml_new(s, sizeof(IMAuxStartCallbackStruct));
    memset(aux, 0, sizeof(IMAuxStartCallbackStruct));
    aux->aux_name = class_name;
    iml_inst *lp = s->If->m->iml_make_aux_start_inst(s, aux);
    s->If->m->iml_execute(s, &lp);

    int int_values[1] = { 0 };
    aux_draw(s, class_name, 1, int_values, 0, NULL);
}

void
aux_done(iml_session_t *s, char *class_name)
{                       
    IMAuxDoneCallbackStruct *aux = (IMAuxDoneCallbackStruct *)
        s->If->m->iml_new(s, sizeof(IMAuxDoneCallbackStruct));
    memset(aux, 0, sizeof(IMAuxDoneCallbackStruct));
    aux->aux_name = class_name;
    iml_inst *lp = s->If->m->iml_make_aux_done_inst(s, aux);
    s->If->m->iml_execute(s, &lp);
}

void
aux_beep(iml_session_t *s)
{
    int int_values[1] = { UNIHAN_AUX_STATUS_BEEP };
    aux_draw(s, AUX_STATUS_CLASS_NAME, 1, int_values, 0, NULL);
}

static int
UTFCHARlen(UTFCHAR *s)
{
	int i = 0;
	if (!s) return 0;
	while (*s) {
		i++; s++;
	}
	return i;
}

void
aux_draw(iml_session_t *s,
         char *class_name,
         int count_integers,
         int *integers,
         int count_strings,
         UTFCHAR **strings)
{
        int i, len;

    IMAuxDrawCallbackStruct *aux = (IMAuxDrawCallbackStruct *)
        s->If->m->iml_new(s, sizeof(IMAuxDrawCallbackStruct));
    memset(aux, 0, sizeof(IMAuxDrawCallbackStruct));
    aux->aux_name = class_name;

    aux->count_integer_values = count_integers;
    if (count_integers) {
        int size = sizeof(int) * count_integers;
        aux->integer_values = (int *) s->If->m->iml_new(s, size);
        memset(aux->integer_values, 0, size);

        for (i = 0; i < count_integers; i++) {
            aux->integer_values[i] = integers[i];
        }
    }

    aux->count_string_values = count_strings;
    if (count_strings) {
        IMText *lts = (IMText *) s->If->m->iml_new(s, sizeof(IMText) * count_strings);
        memset(lts, 0, sizeof(IMText) * count_strings);
        IMText *lt;
        for (i = 0, lt = lts; i < count_strings; i++, lt++) {
            len = UTFCHARlen(strings[i]);
            lt->text.utf_chars = (UTFCHAR *) s->If->m->iml_new(s, sizeof(UTFCHAR) * len);
            lt->char_length = len;
            memcpy(lt->text.utf_chars, strings[i], sizeof(UTFCHAR) * len);
        }
        aux->string_values = lts;
    }

    iml_inst *lp = s->If->m->iml_make_aux_draw_inst(s, aux);
    s->If->m->iml_execute(s, &lp);
}

void
punc_keyboard_hide(iml_session_t *s)
{
	int int_values[2];

	/* tell lookup to hide the virtual keyboard */
	int_values[0] = UNIHAN_AUX_PUNC_KEYBOARD_HIDE;
	aux_draw(s, AUX_LOOKUP_CLASS_NAME, 1, int_values, 0, NULL);

	/* tell status to de-activate the menu item */
	int_values[0] = UNIHAN_AUX_STATUS_PUNC_KEYBOARD;
	int_values[1] = 0;
	aux_draw(s, AUX_STATUS_CLASS_NAME, 2, int_values, 0, NULL);
}

void
punc_keyboard_show(iml_session_t *s)
{
	int int_values[2];

	/* tell lookup to draw the virtual keyboard */
	int_values[0] = UNIHAN_AUX_PUNC_KEYBOARD_SHOW;
	aux_draw(s, AUX_LOOKUP_CLASS_NAME, 1, int_values, 0, NULL);

	/* tell status to activate the menu item */
	int_values[0] = UNIHAN_AUX_STATUS_PUNC_KEYBOARD;
	int_values[1] = 1;
	aux_draw(s, AUX_STATUS_CLASS_NAME, 2, int_values, 0, NULL);
}

void
us_keyboard_hide(iml_session_t *s)
{
	int int_values[2];

	/* tell lookup to hide the virtual keyboard */
	int_values[0] = UNIHAN_AUX_US_KEYBOARD_HIDE;
	aux_draw(s, AUX_LOOKUP_CLASS_NAME, 1, int_values, 0, NULL);

	/* tell status to de-activate the menu item */
	int_values[0] = UNIHAN_AUX_STATUS_US_KEYBOARD;
	int_values[1] = 0;
	aux_draw(s, AUX_STATUS_CLASS_NAME, 2, int_values, 0, NULL);
}

void
us_keyboard_show(iml_session_t *s)
{
	int int_values[3];
	DataPerSession *ds = (DataPerSession *)s->specific_data;

	/* tell lookup to draw the virtual keyboard */
	int_values[0] = UNIHAN_AUX_US_KEYBOARD_SHOW;
	int_values[1] = ds->us_kbd_caps_pressed;
	int_values[2] = ds->us_kbd_shift_pressed;
	aux_draw(s, AUX_LOOKUP_CLASS_NAME, 3, int_values, 0, NULL);

	/* tell status to activate the menu item */
	int_values[0] = UNIHAN_AUX_STATUS_US_KEYBOARD;
	int_values[1] = 1;
	aux_draw(s, AUX_STATUS_CLASS_NAME, 2, int_values, 0, NULL);
}

void
lost_focus_notify(iml_session_t *s)
{
        int int_values[1] = { UNIHAN_AUX_LOST_FOCUS };
        aux_draw(s, AUX_STATUS_CLASS_NAME, 1, int_values, 0, NULL);
}


/***************************************************************************/
void
tooltip_update_im(iml_session_t *s)
{
        DataPerSession *ds = (DataPerSession *)s->specific_data;
        
        int int_values[1];
        UTFCHAR *string_values[1];

        int_values[0] = UNIHAN_AUX_TOOLTIP_DRAW;

        if (ds->conv_on != 1) {
                string_values[0] = utf8_to_utf16be(s, (UTF8CHAR *)"English", NULL);
        } else {
                string_values[0] = utf8_to_utf16be(s, (UTF8CHAR *)im_get_curr_im_name(s), NULL);
        }

        aux_draw(s, AUX_LOOKUP_CLASS_NAME, 1, int_values, 1, string_values);
}

/***************************************************************************/
void
tooltip_update_width(iml_session_t *s, int is_full)
{
    //DataPerSession *ds = (DataPerSession *)s->specific_data;
    int int_values[1];

	if (is_full)
		int_values[0] = UNIHAN_AUX_TOOLTIP_FULLWIDTH;
	else
		int_values[0] = UNIHAN_AUX_TOOLTIP_HALFWIDTH;

    aux_draw(s, AUX_LOOKUP_CLASS_NAME, 1, int_values, 0, NULL);
}

/***************************************************************************/
void
tooltip_update_puncce(iml_session_t *s, int is_ch)
{
    //DataPerSession *ds = (DataPerSession *)s->specific_data;
    int int_values[1];

	if (is_ch)
		int_values[0] = UNIHAN_AUX_TOOLTIP_CHINESEPUNC;
	else
		int_values[0] = UNIHAN_AUX_TOOLTIP_ENGLISHPUNC;

    aux_draw(s, AUX_LOOKUP_CLASS_NAME, 1, int_values, 0, NULL);
}

/***************************************************************************/
void
tooltip_update_tcsc(iml_session_t *s)
{
    DataPerDesktop *dd = (DataPerDesktop *)s->desktop->specific_data;
    int int_values[2];

    int_values[0] = UNIHAN_AUX_TOOLTIP_TCSC_MODE;
	int_values[1] = dd->tcsc;

    aux_draw(s, AUX_LOOKUP_CLASS_NAME, 2, int_values, 0, NULL);
}

// vi:ts=4:sw=4:nowrap:cin:expandtab
